import { useRefValue } from '@gnlab/utils/env-react'
import { Spin, Modal, Input, Button, Tag, Tooltip, message } from 'antd'
import type { OrderedMap } from 'immutable'
import ChooseTags from '@/desktop/components/ChooseExternalTags'
import services from '@/services'
import type { ExternalTag as QywxTag } from '@/services/contact-types'
import type { DescribeToTagsRule } from '@/services/features/describe-to-tags'
import './Edit.module.less'

export default function EditModal(props: {
  editing: false | true | DescribeToTagsRule
  onFinish: () => void
  tagsMap: Map<string, QywxTag>
  corps: OrderedMap<string, string>
}) {
  const { editing, onFinish, tagsMap, corps } = props

  const title = editing !== false ? (editing === true ? '新建规则' : '编辑规则') : ''

  return <Modal
    title={title}
    footer={null}
    width="600px"
    open={editing !== false}
    onCancel={onFinish}
    destroyOnClose
  >
    {editing !== false ? (
      <Content editing={editing} onFinish={onFinish} tagsMap={tagsMap} corps={corps} />
    ) : null}
  </Modal>
}

function Content(props: {
  editing: true | DescribeToTagsRule
  onFinish: () => void
  tagsMap: Map<string, QywxTag>
  corps: OrderedMap<string, string>
}) {
  const { editing, onFinish, tagsMap, corps } = props

  const [match, setMatch] = useState(editing !== true ? editing.match : '')
  const [tagIds, setTagIds] = useState(editing !== true ? editing.tagIds : [])
  const tagIdsRef = useRefValue(tagIds)

  const [choosingTags, setChoosingTags] = useState(false)
  const onChoosed = useCallback((choosed?: { id: string }[]) => {
    if (choosed) setTagIds(choosed.map(t => t.id))
    setChoosingTags(false)
  }, [])

  const removeTag = useCallback(
    (id: string) => {
      const ids = tagIdsRef.current
      setTagIds(ids.filter(_id => _id !== id))
    },
    [tagIdsRef],
  )

  const [submitting, setSubmitting] = useState(false)
  const save = useCallback(async () => {
    if (!match) return void message.error('描述内容不能为空')

    setSubmitting(true)
    const res = await services.features.describeToTags.addOrUpdate({
      id: editing === true ? undefined : editing.id,
      match,
      tagIds,
    })
    setSubmitting(false)

    if (res.success) {
      void message.success('规则保存成功！')
      onFinish()
    } else {
      void message.warning(`规则保存失败：${res.error}`)
    }
  }, [editing, match, tagIds, onFinish])

  const content = <div styleName="edit">
    <section>
      <label>描述内容：</label>
      <div>
        <Input
          value={match}
          onChange={e => setMatch(e.target.value)}
          placeholder='输入要匹配的描述内容，无需带 "$tag:" 和 ":$" 前后缀'
        />
        {match ? (
          <div styleName="preview">
            $tag:<span>{match}</span>:$
          </div>
        ) : null}
      </div>
    </section>

    <section>
      <label>选择标签：</label>
      <div styleName="tags">
        {tagIds.map(id => {
          const tag = tagsMap.get(id)
          if (!tag) return null

          return <Tooltip key={id} title={`公司：${corps.get(tag.corpid) ?? ''}`}>
            <Tag closable onClose={() => removeTag(id)}>
              {tag.name}
            </Tag>
          </Tooltip>
        })}

        <Tag styleName="add-tag" title="选择标签" onClick={() => setChoosingTags(true)}>
          +
        </Tag>
      </div>
    </section>

    <section>
      <label></label>
      <div>
        <Button type="primary" onClick={save}>
          保存
        </Button>
      </div>
    </section>

    <ChooseTags visible={choosingTags} choosed={tagIds} onFinish={onChoosed} />
  </div>

  return submitting ? <Spin>{content}</Spin> : content
}
